package com.itheima.consumer.controller;


import com.itheima.consumer.domain.Goods;
import com.itheima.consumer.feign.GoodsFeign;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;


/**
 * 服务的调用方
 */

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private GoodsFeign goodsFeign;

    @Value("${server.port}")
    private String port;

    @GetMapping("/goods/{id}")
    @HystrixCommand(fallbackMethod = "fallMethod")
    public Goods findGoodsById(@PathVariable("id") int id){
        System.out.println("findGoodsById..."+id);

        /*
         方式一：
           硬编码：
            1.生产者ip或者端口号发生变化导致代码需要重新修改部署--eureka
            2.无法完成集群的负载调用---ribbon
            3.无法感知生产者服务状态--hystrix 熔断器

         */
        //String url = "http://127.0.0.1:8000/goods/findOne/" + id;
		//远程调用Goods服务中的findOne接口


        /*
            方式二：discoveryClient查询eureka获取服务列表
         */
        //1、通过discoveryClient根据服务的应用名称从注册中心查询服务列表
      /*  List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");
        //2、由于目前只有一台生产者所以此处可以get 0
        ServiceInstance serviceInstance = instances.get(0);
        //3、获取uri
        URI uri = serviceInstance.getUri();
        System.out.println("uri: " + uri);
        //4.完成url拼接
        String url = uri + "/goods/findOne/" + id;*/


        /*
            方式三： 通过ribbon调用
                ribbon会通过服务的应用名称从注册中心获取服务列表并且完成负载
         */
        /*String url = "http://eureka-provider/goods/findOne/"+ id;
        Goods goods = restTemplate.getForObject(url, Goods.class);*/

        /*
            方式四： 使用feign调用
         */
        Goods goods = goodsFeign.findOne(id);
        goods.setTitle(goods.getTitle() + " 消费者端口号： " + port);
        return goods;
    }

    /**
     * @Author: guodong 
     * @Date: 14:07 2020/11/7
     * @Parms [serviceId]
     * @ReturnType: java.util.List<org.springframework.cloud.client.ServiceInstance>
     * @Description: 用户获取服务列表
    */
    @GetMapping("getInstance/{serviceId}")
    public List<ServiceInstance> getInstance(@PathVariable String serviceId){
        List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");
        return instances;
    }

    /*
        默认的服务降级方法：
            1.返回值类型与原方法必须一致
            2.参数列表与原方法必须一致
     */
    public Goods fallMethod(int id){
        Goods goods = new Goods();
        goods.setId(id);
        goods.setTitle("默认的服务降级方法...");
        return goods;
    }
}
